package com.way.view;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.SimpleAdapter;

import com.way.popup.R;
import com.way.popup.R.dimen;
import com.way.popup.R.id;
import com.way.popup.R.layout;
import com.way.popup.R.style;
import com.way.util.Util;

//A popup window that contains a big thumbnail and a list of apps to share.
public class SharePopup extends PopupWindow implements View.OnClickListener,
		View.OnTouchListener, AdapterView.OnItemClickListener, Rotatable {
	private static final String TAG = "SharePopup";
	private static final String ADAPTER_COLUMN_ICON = "icon";
	private Context mContext;
	private Uri mUri;
	private String mMimeType;
	private ImageView mThumbnail;
	private int mBitmapWidth;
	private int mBitmapHeight;
	private int mOrientation;
	private int mActivityOrientation;
	// A view that contains a list of application icons and the share view.
	private View mRootView;
	// The list of the application icons.
	private GridView mShareList;
	// A rotated view that contains the thumbnail and the play icon.
	private RotateLayout mThumbnailRotateLayout;
	private RotateLayout mGotoGalleryRotate;
	// private View mPreviewFrame;
	private ArrayList<ComponentName> mComponent = new ArrayList<ComponentName>();
	private View mImageViewFrame;

	private class MySimpleAdapter extends SimpleAdapter {
		public MySimpleAdapter(Context context,
				List<? extends Map<String, ?>> data, int resource,
				String[] from, int[] to) {
			super(context, data, resource, from, to);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View v = super.getView(position, convertView, parent);
			RotateLayout r = (RotateLayout) v
					.findViewById(R.id.share_icon_rotate_layout);
			r.setOrientation(mOrientation);
			return v;
		}
	}

	private final SimpleAdapter.ViewBinder mViewBinder = new SimpleAdapter.ViewBinder() {
		@Override
		public boolean setViewValue(final View view, final Object data,
				final String text) {
			if (view instanceof ImageView) {
				((ImageView) view).setImageDrawable((Drawable) data);
				return true;
			}
			return false;
		}
	};
	private DisplayMetrics dm;

	public SharePopup(Activity activity, Uri uri, Bitmap bitmap, int orientation) {
		super(activity);
		dm = new DisplayMetrics();
		activity.getWindowManager().getDefaultDisplay().getMetrics(dm);

		mActivityOrientation = activity.getRequestedOrientation();

		// Initialize variables
		mContext = activity;
		if (uri != null) {
			mUri = uri;
			mMimeType = mContext.getContentResolver().getType(mUri);
			if (null == mMimeType) {
				// throw (new RuntimeException(
				// "can't get mimetype from content resolver"));
				mMimeType = "image/*";
			}
		}
		LayoutInflater inflater = activity.getLayoutInflater();
		ViewGroup sharePopup = (ViewGroup) inflater.inflate(
				R.layout.share_popup, null, false);
		// This is required because popup window is full screen.
		if (sharePopup != null) {
			sharePopup.setOnTouchListener(this);
			mThumbnailRotateLayout = (RotateLayout) sharePopup
					.findViewById(R.id.thumbnail_rotate_layout);
			mShareList = (GridView) sharePopup.findViewById(R.id.share_list);
			mThumbnail = (ImageView) sharePopup.findViewById(R.id.thumbnail);
		}
		if (bitmap != null) {
			mThumbnail.setImageBitmap(bitmap);
		}
		if (sharePopup != null) {
			mImageViewFrame = (View) sharePopup
					.findViewById(R.id.thumbnail_image_frame);
			mImageViewFrame.setOnClickListener(this);
			mGotoGalleryRotate = (RotateLayout) sharePopup
					.findViewById(R.id.goto_gallery_button_rotate);
			sharePopup.findViewById(R.id.goto_gallery_button)
					.setOnClickListener(this);
		}

		mBitmapWidth = bitmap.getWidth();
		mBitmapHeight = bitmap.getHeight();

		// Show play button if this is a video thumbnail.
		if (mMimeType.startsWith("video/")) {
			sharePopup.findViewById(R.id.play).setVisibility(View.VISIBLE);
		}
		mBitmapWidth = bitmap.getWidth();
		mBitmapHeight = bitmap.getHeight();

		Resources res = mContext.getResources();

		// Initialize popup window size.
		mRootView = sharePopup.findViewById(R.id.root);
		LayoutParams params = mRootView.getLayoutParams();
		params.width = dm.widthPixels;
		params.height = dm.heightPixels;
		mRootView.setLayoutParams(params);

		// Initialize popup window.
		setWidth(WindowManager.LayoutParams.MATCH_PARENT);
		setHeight(WindowManager.LayoutParams.MATCH_PARENT);
		setBackgroundDrawable(new ColorDrawable());
		setContentView(sharePopup);
		setOrientation(orientation);
		setFocusable(true);
		setAnimationStyle(R.style.AnimationPopup);
		createShareMenu();
	}

	public void setOrientation(int orientation) {
		mOrientation = orientation;

		int hPaddingRootView = mRootView.getPaddingLeft()
				+ mRootView.getPaddingRight();
		int vPaddingRootView = mRootView.getPaddingTop()
				+ mRootView.getPaddingBottom();

		// Calculate the width and the height of the thumbnail. Reserve the
		// space for paddings(half space of paddings for bug 2503 ,in order to
		// make true
		// to keep rate of width and height ).
		float maxWidth = dm.widthPixels - hPaddingRootView;
		float maxHeight = dm.heightPixels - vPaddingRootView / 2;
		// Swap the width and height if it is portrait mode.
		if (orientation == 90 || orientation == 270) {
			float temp = maxWidth;
			maxWidth = maxHeight;
			maxHeight = temp;
		}
		float actualAspect = maxWidth / maxHeight;
		float desiredAspect = (float) mBitmapWidth / mBitmapHeight;

		if (mMimeType.startsWith("video/")) {
			// for fixed bug 216
			if (desiredAspect > 1) {
				desiredAspect = 4F / 3F;
			} else {
				desiredAspect = 3F / 4F;
			}
			mThumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP);
		} else {
			mThumbnail.setScaleType(ImageView.ScaleType.FIT_CENTER);
		}

		LayoutParams params = mThumbnail.getLayoutParams();
		if (actualAspect > desiredAspect) {
			params.width = Math.round(maxHeight * desiredAspect);
			params.height = Math.round(maxHeight);
		} else {
			params.width = Math.round(maxWidth);
			params.height = Math.round(maxWidth / desiredAspect);
		}
		mThumbnail.setLayoutParams(params);

		if (mThumbnailRotateLayout != null)
			mThumbnailRotateLayout.setOrientation(orientation);

		int count = mShareList.getChildCount();
		for (int i = 0; i < count; i++) {
			ViewGroup f = (ViewGroup) mShareList.getChildAt(i);
			RotateLayout r = (RotateLayout) f
					.findViewById(R.id.share_icon_rotate_layout);
			r.setOrientation(orientation);
		}

		mGotoGalleryRotate.setOrientation(orientation);
	}

	@Override
	public void showAtLocation(View parent, int gravity, int x, int y) {
		super.showAtLocation(parent, gravity, x, y);
		// Inform other popup to dismiss if exit
		PopupManager.getInstance(mContext).notifyShowPopup(null);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.goto_gallery_button:
		case R.id.thumbnail_image_frame:
			Util.viewUri(mUri, mContext);
			break;
		}
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			dismiss();
			return true;
		}
		return false;
	}

	public void createShareMenu() {
		PackageManager packageManager = mContext.getPackageManager();
		List<ResolveInfo> infos = packageManager.queryIntentActivities(
				new Intent(Intent.ACTION_SEND).setType(mMimeType), 0);

		ArrayList<HashMap<String, Object>> items = new ArrayList<HashMap<String, Object>>();
		for (ResolveInfo info : infos) {
			ComponentName component = new ComponentName(
					info.activityInfo.packageName, info.activityInfo.name);

			if (info.activityInfo.packageName.equals("com.android.bluetooth")
					&& info.activityInfo.name
							.equals("com.android.bluetooth.opp.BluetoothOppLauncherActivity")) {
				Log.d(TAG, "miss package name=" + info.activityInfo.packageName
						+ "  activity name=" + info.activityInfo.name);
				continue;
			}

			HashMap<String, Object> map = new HashMap<String, Object>();
			map.put(ADAPTER_COLUMN_ICON, info.loadIcon(packageManager));
			items.add(map);
			mComponent.add(component);
		}

		// On phone UI, we have to know how many icons in the grid view before
		// the view is measured.
		// if (mActivityOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
		// {
		mShareList.setNumColumns(items.size());
		int width = mContext.getResources().getDimensionPixelSize(
				R.dimen.share_item_width);
		mShareList.setColumnWidth(width);
		// }

		SimpleAdapter listItemAdapter = new MySimpleAdapter(mContext, items,
				R.layout.share_icon, new String[] { ADAPTER_COLUMN_ICON },
				new int[] { R.id.icon });

		listItemAdapter.setViewBinder(mViewBinder);
		mShareList.setAdapter(listItemAdapter);
		mShareList.setOnItemClickListener(this);
	}

	public Uri getUri() {
		return mUri;
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int index, long id) {
		Intent intent = new Intent(Intent.ACTION_SEND);
		intent.setType(mMimeType);
		intent.putExtra(Intent.EXTRA_STREAM, mUri);
		intent.setComponent(mComponent.get(index));
		mContext.startActivity(intent);
	}
}
